package com.hoopchina.weibo;

/**
 * 
 * @author neusoft
 *
 */
import java.io.File;

import org.apache.http.HttpStatus;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

import com.hoopchina.util.URLEncodeUtils;
import com.hoopchina.weibo.WeiboType;
import com.hoopchina.weibo.http.AccessToken;
import com.hoopchina.weibo.http.HttpClient;
import com.hoopchina.weibo.http.ImageItem;
import com.hoopchina.weibo.http.PostParameter;
import com.hoopchina.weibo.http.RequestToken;
import com.hoopchina.weibo.http.Response;
import com.hoopchina.weibo.http.User;

public class Weibo extends WeiboSupport implements java.io.Serializable {
	private static final String TAG = "Weibo";
	private static final long serialVersionUID = -1486360080128882436L;
	public static int mType;
	public RequestToken mRequestToken = null;
	public AccessToken mAccessToken = null;
	private static Weibo mInstance = null;
	private String mBaseURL = "";

	/**
	 * 获取实例
	 */
	public static synchronized Weibo getInstance(int type) {
		if (mInstance == null)
		{
			mInstance = new Weibo(type);
		}
		else {
			if (mType == type) {
				return mInstance;
			} else {
				try {
					mInstance.finalize();
					mInstance = new Weibo(type);
				} catch (Throwable e) {
					e.printStackTrace();
				}
			}
		}
		return mInstance;
	}

	/**
	 * 获取一个新的实例
	 */
	public static synchronized Weibo getNewInstance(int type) {
		if (mInstance == null)
		{
			mInstance = new Weibo(type);
		}
		else {
			try {
				mInstance.finalize();
				mInstance = new Weibo(type);
			} catch (Throwable e) {
				e.printStackTrace();
			}
		}
		return mInstance;
	}

	public AccessToken getAccessToken(String pin) {
		try {
			mAccessToken = mRequestToken.getAccessToken(mType, pin);
			return mAccessToken;
		} catch (WeiboException e) {
			e.printStackTrace();
		}
		return null;
	}

	public int publishMsg(String msg) {
		Response res = null;
		switch (mType) {
		case WeiboType.SinaType:
			try {
				res = updateStatus(msg);
				Log.i("Weibo","res.getStatusCode():"+res.getStatusCode());
				Log.i("Weibo","res.asString():"+res.asString());
				if(res.getStatusCode()==HttpStatus.SC_OK)
				{
			    	return 0;
				} 
			} catch (WeiboException e) {
				try {
					Log.i(TAG,e.getMessage());
				    JSONObject root = new JSONObject( e.getMessage() );
				    String errorMsg = root.getString( "error" );
				    return Integer.parseInt(errorMsg.substring(0, errorMsg.indexOf(':')));
				} catch (JSONException ee) {
					e.printStackTrace();
				}
			}
			break;
		case WeiboType.TencentType:
			try {
				res = updateTencentStatus(msg);
				Log.i("Weibo","res.getStatusCode():"+res.getStatusCode());
				Log.i("Weibo","res.asString():"+res.asString());
				if(res.getStatusCode()==HttpStatus.SC_OK)
				{	
			    	JSONObject root = new JSONObject( res.asString() );
					return root.getInt( "errcode" );
				} 
			} catch (WeiboException e) {
				Log.e("Weibo","WeiboException error");
				e.printStackTrace();
			} catch (JSONException e) {
				Log.e("Weibo","JSONException error");
				e.printStackTrace();
			}
			break;
		case WeiboType.SohuType:
			try {
				res = updateStatus(msg);
				Log.i("Weibo","res.getStatusCode():"+res.getStatusCode());
				Log.i("Weibo","res.asString():"+res.asString());
				if(res.getStatusCode()==HttpStatus.SC_OK)
				{
			    	return 0;
				} 
			} catch (WeiboException e) {
				try {
					Log.i(TAG,e.getMessage());
				    JSONObject root = new JSONObject( e.getMessage() );
				    return Integer.parseInt(root.getString( "code" ));
				} catch (JSONException ee) {
					e.printStackTrace();
				}
			}
			break;
		case WeiboType.NetEaseType:
			try {
				res = updateT163Status(msg);
				Log.i("Weibo","res.getStatusCode():"+res.getStatusCode());
				Log.i("Weibo","res.asString():"+res.asString());
				if(res.getStatusCode()==HttpStatus.SC_OK)
				{	
					return 0;
				} 
			} catch (WeiboException e) {
				Log.e("Weibo","WeiboException error");
				e.printStackTrace();
			}
			break;
		}
		return -1;
	}

	/**
	 * 验证当前用户身份是否合法
	 * 
	 * @return user
	 * @since Weibo4J 1.2.0
	 * @throws WeiboException
	 *             when Weibo service or network is unavailable
	 * @see <a
	 *      href="http://open.t.sina.com.cn/wiki/index.php/Account/verify_credentials">account/verify_credentials
	 *      </a>
	 */
	public User verifyCredentials() throws WeiboException {
		Log.i(TAG,"verifyCredentials enter");
		Response res = null;
		try
		{
			switch (mType) {
			case WeiboType.SinaType:
				res = http.httpRequest(
						mBaseURL + "account/verify_credentials.json", null,true);
			case WeiboType.TencentType:
				res = http.httpRequest3(
						mBaseURL + "api/user/info?format=json", null,true);
			case WeiboType.SohuType:
				res = http.httpRequest(
						mBaseURL + "account/verify_credentials.json", null,true);
			case WeiboType.NetEaseType:
				res = http.httpRequest(
						mBaseURL + "account/verify_credentials.json", null,true);
			}
		}
		catch(WeiboException e)
		{
//			if(e.getStatusCode() != NOT_AUTHORIZED )
//			{
//				Log.i(TAG,"verifyCredentials error");
//				e.printStackTrace();
//				return null;
//			}
		}
		Log.i(TAG,"verifyCredentials exit");
		return new User(res.asString(), mType);
	}

	/**
	 * 上传图片文件并返回图片地址
	 * 
	 * @param file
	 *            支持jpg、png、bmp、gif这四种图片格式
	 * @return
	 * @throws TBlogException
	 */
	public String updateImage(File file) throws WeiboException {// xieyongqiang
		String resStr = http.multPartURL("pic",
				mBaseURL + "statuses/upload.json", new PostParameter[0],
				file, true).asString();
		String uploadImageUrl = "";
		// try{
		// if(!json.isNull("upload_image_url")){
		// return json.getString("upload_image_url");
		// }else{
		// return "";
		// }
		// }catch (JSONException jsone) {
		// throw new WeiboException(jsone);
		// }
		try {
			JSONObject root = new JSONObject(resStr);
			uploadImageUrl = root.getString("upload_image_url").trim();

		} catch (JSONException e) {
			e.printStackTrace();
		}
		return uploadImageUrl;
	}

	/**
	 * 发布一条微博信息
	 * 
	 * @param status
	 *            要发布的微博消息文本内容
	 * @return the latest status
	 * @throws WeiboException
	 *             when Weibo service or network is unavailable
	 * @since Weibo4J 1.2.0
	 * @see <a
	 *      href="http://open.t.sina.com.cn/wiki/index.php/Statuses/update">statuses/update
	 *      </a>
	 */
	public Response updateStatus(String status) throws WeiboException {
		setToken(mAccessToken.getToken(), mAccessToken.getTokenSecret());
		return http.post(mBaseURL + "statuses/update.json",
				new PostParameter[] { new PostParameter("status", status) },
				true);
	}

	/**
	 * 发布一条微博信息
	 * 
	 * @param status
	 *            要发布的微博消息文本内容
	 * @return the latest status
	 * @throws WeiboException
	 *             when Weibo service or network is unavailable
	 * @since Weibo4J 1.2.0
	 * @see <a
	 *      href="http://open.t.sina.com.cn/wiki/index.php/Statuses/update">statuses/update
	 *      </a>
	 */
	public Response updateT163Status(String status) throws WeiboException {
		return http.t163Post(mBaseURL + "statuses/update.json",
				new PostParameter[] { new PostParameter("status", status) },
				true);
	}

	public Response updateTencentStatus(String status) throws WeiboException {
		return http.tencentPost(mBaseURL + "api/t/add", new PostParameter[] {
				new PostParameter("content", status),
				new PostParameter("format", "json"),
				new PostParameter("clientip", "127.0.0.1") }, true);
	}

	public String publishMsg(String customKey, String customSecret,
			String requestToken, String requestTokenSecrect, String content,
			String pic) {

		String url = null;
		String httpMethod = "POST";

		if (pic == null || pic.trim().equals("")) {
			url = "http://open.t.qq.com/api/t/add";
		} else {
			url = "http://open.t.qq.com/api/t/add_pic";
		}

		String strFormat = "json";
		String res = null;
		try {
			http.tencentSyncRequest(url, httpMethod, customKey, customSecret,
					requestToken, requestTokenSecrect, strFormat, new String(
							content.getBytes("UTF-8")), "127.0.0.1", pic);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return res;
	}

	/**
	 * 发表图片微博消息。目前上传图片大小限制为<5M。
	 * 
	 * @param status
	 *            要发布的微博消息文本内容
	 * @param item
	 *            要上传的图片
	 * @return the latest status
	 * @throws WeiboException
	 *             when Weibo service or network is unavailable
	 * @since Weibo4J 1.2.0
	 * @see <a
	 *      href="http://open.t.sina.com.cn/wiki/index.php/Statuses/upload">statuses/upload
	 *      </a>
	 */
	public int uploadStatus(String status, ImageItem item)
			throws WeiboException {
		if (!URLEncodeUtils.isURLEncoded(status))
			status = URLEncodeUtils.encodeURL(status);
		
		Response res = null;
		try {
			res = http.multPartURL(mBaseURL + "statuses/upload.json",
					new PostParameter[] { new PostParameter("status", status),
				new PostParameter("source", source) }, item, true);
			Log.i("Weibo","res.getStatusCode():"+res.getStatusCode());
			Log.i("Weibo","res.asString():"+res.asString());
		} catch (WeiboException e) {
			e.printStackTrace();
			return -1;
		}
		if(res.getStatusCode()==HttpStatus.SC_OK)
		{
	    	return 0;
		}
		else
		{
			try {
			    JSONObject root = new JSONObject( res.asString() );
			    String errorMsg = root.getString( "error" );
			    errorMsg.substring(0, errorMsg.indexOf(':'));
			    return Integer.parseInt(errorMsg.substring(0, errorMsg.indexOf(':')));
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
		return -1;
	}

	public int TencentUploadStatus(String status, ImageItem item)
			throws WeiboException {
		Response res = http.tencentMultPartURL(mBaseURL + "api/t/add_pic",
				new PostParameter[] { new PostParameter("format", "json"),
						new PostParameter("content", status),
						new PostParameter("clientip", "127.0.0.1") }, item,
				true);
		try {
			if(res.getStatusCode()==HttpStatus.SC_OK)
			{	
		    	JSONObject root = new JSONObject( res.asString() );
				return root.getInt( "errcode" );
			} 
		} catch (WeiboException e) {
			e.printStackTrace();
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return -1;
	}

	public RequestToken getOAuthRequestToken(int weiboType)
			throws WeiboException {
		if (mRequestToken == null) {
			mRequestToken = http.getOAuthRequestToken(weiboType);
		}
		return mRequestToken;
	}

	/**
	 * 初始化参数
	 */
	public Weibo(int type) {
		super(type);
		mType = type;
		switch (type) {
		case WeiboType.SinaType:
			mBaseURL = "http://api.t.sina.com.cn/";
			http.setRequestTokenURL("http://api.t.sina.com.cn/oauth/request_token");
			http.setAuthorizationURL("http://api.t.sina.com.cn/oauth/authorize");
			http.setAccessTokenURL("http://api.t.sina.com.cn/oauth/access_token");
			break;
		case WeiboType.NetEaseType:
			mBaseURL = "http://api.t.163.com/";
			http.setRequestTokenURL("http://api.t.163.com/oauth/request_token");
			http.setAuthorizationURL("http://api.t.163.com/oauth/authorize");
			http.setAccessTokenURL("http://api.t.163.com/oauth/access_token");
			break;
		case WeiboType.TencentType:
			mBaseURL = "http://open.t.qq.com/";
			http.setRequestTokenURL("http://open.t.qq.com/cgi-bin/request_token");
			http.setAuthorizationURL("http://open.t.qq.com/cgi-bin/authorize");
			http.setAccessTokenURL("http://open.t.qq.com/cgi-bin/access_token");
			break;
		case WeiboType.SohuType:
			mBaseURL = "http://api.t.sohu.com/";
			http.setRequestTokenURL("http://api.t.sohu.com/oauth/request_token");
			http.setAuthorizationURL("http://api.t.sohu.com/oauth/authorize");
			http.setAccessTokenURL("http://api.t.sohu.com/oauth/access_token");
			break;
		}
		System.setProperty("weibo.oauth.consumerKey", Weibo.CONSUMER_KEY);
		System.setProperty("weibo.oauth.consumerSecret",
				Weibo.CONSUMER_SECRET);
		System.setProperty("http.keepAlive", "false");
	}

	/**
	 * 设置Token
	 */
	public void setToken(String token, String tokenSecret) {
		http.setToken(token, tokenSecret);
	}

	protected Response get(String url, PostParameter[] params,
			boolean authenticate) throws WeiboException {
		if (null != params && params.length > 0) {
			url += "&" + HttpClient.encodeParameters(params);
		}
		return http.get(url, authenticate);
	}
}